home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / sprite.X11R3 / RCS / pdev.c,v < prev    next >
Encoding:
Text File  |  1989-10-26  |  57.0 KB  |  2,186 lines

  1. head     1.12;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.12
  10. date     89.06.22.09.38.41;  author ouster;  state Exp;
  11. branches ;
  12. next     1.11;
  13.  
  14. 1.11
  15. date     89.06.01.10.44.09;  author brent;  state Exp;
  16. branches ;
  17. next     1.10;
  18.  
  19. 1.10
  20. date     88.11.28.10.37.45;  author ouster;  state Exp;
  21. branches ;
  22. next     1.9;
  23.  
  24. 1.9
  25. date     88.10.01.10.55.51;  author ouster;  state Exp;
  26. branches ;
  27. next     1.8;
  28.  
  29. 1.8
  30. date     88.09.16.10.57.37;  author ouster;  state Exp;
  31. branches ;
  32. next     1.7;
  33.  
  34. 1.7
  35. date     88.09.11.13.09.20;  author ouster;  state Exp;
  36. branches ;
  37. next     1.6;
  38.  
  39. 1.6
  40. date     88.09.11.13.01.04;  author ouster;  state Exp;
  41. branches ;
  42. next     1.5;
  43.  
  44. 1.5
  45. date     88.09.09.18.00.25;  author ouster;  state Exp;
  46. branches ;
  47. next     1.4;
  48.  
  49. 1.4
  50. date     88.09.08.18.15.52;  author ouster;  state Exp;
  51. branches ;
  52. next     1.3;
  53.  
  54. 1.3
  55. date     88.08.26.16.13.09;  author brent;  state Exp;
  56. branches ;
  57. next     1.2;
  58.  
  59. 1.2
  60. date     88.08.26.08.56.51;  author deboor;  state Exp;
  61. branches ;
  62. next     1.1;
  63.  
  64. 1.1
  65. date     87.11.29.19.51.59;  author deboor;  state Exp;
  66. branches ;
  67. next     ;
  68.  
  69.  
  70. desc
  71. @Functions to support connections using the second-generation pseudo-devices
  72. @
  73.  
  74.  
  75. 1.12
  76. log
  77. @Changes for new pdev code (large vs. small replies, signal returns).
  78. @
  79. text
  80. @/*-
  81.  * pdev.c --
  82.  *    Functions for handling a connection to a client over a pseudo-device.
  83.  *
  84.  *    For each client, we have two buffers -- a 2K output buffer, from
  85.  *    which the client reads, and a 2K request buffer, to which it writes.
  86.  *    The size for the output buffer is based on examination of the size
  87.  *    of buffers used in the old pseudo-device implementation. None
  88.  *    was larger than 2K, so... The input buffer size is based on the
  89.  *    size of Xlib's output buffer -- 2K. This is obviously inadequate for
  90.  *    large amounts of image data, but for most applications it should
  91.  *    be fine.
  92.  *
  93.  *    Requests are processed from the request buffer in order, obviously,
  94.  *    with a write request remaining current until all its data have been
  95.  *    consumed. If an X request crosses a pdev request boundary, it is
  96.  *    copied and collected in a separate area, which is deallocated on the
  97.  *    next call. X requests wholy inside a pdev request are left in the
  98.  *    buffer. The kernel is not told the pdev request has been processed
  99.  *    until all X requests in the pdev request have been handled.
  100.  *
  101.  *    Each time data are written to the read buffer, the pointers are
  102.  *    updated. The stream is not read until the request buffer has
  103.  *    been exhausted.
  104.  *
  105.  * Copyright (c) 1987 by the Regents of the University of California
  106.  *
  107.  * Permission to use, copy, modify, and distribute this
  108.  * software and its documentation for any purpose and without
  109.  * fee is hereby granted, provided that the above copyright
  110.  * notice appear in all copies.  The University of California
  111.  * makes no representations about the suitability of this
  112.  * software for any purpose.  It is provided "as is" without
  113.  * express or implied warranty.
  114.  *
  115.  *
  116.  */
  117. #ifndef lint
  118. static char rcsid[] =
  119. "$Header: /a/X/src/cmds/Xsprite/os/RCS/pdev.c,v 1.11 89/06/01 10:44:09 brent Exp Locker: brent $ SPRITE (Berkeley)";
  120. #endif lint
  121.  
  122. #define NEED_REPLIES /* For Debugging Only */
  123.  
  124. /*
  125.  * These first two header files must indeed be first, or else this
  126.  * file won't compile.
  127.  */
  128.  
  129. #define Time SpriteTime
  130. #include    <fs.h>
  131. #undef Time
  132. #include    <stdlib.h>
  133.  
  134. #include    "spriteos.h"
  135.  
  136. #include    "Xproto.h"
  137. #include    "opaque.h"
  138.  
  139. #include    <bit.h>
  140. #include    <dev/pdev.h>
  141. #include    <errno.h>
  142. #include    <status.h>
  143. #include    <stdio.h>
  144. #include    <sys/time.h>
  145.  
  146. /*
  147.  * Template for the pseudo-device through which we communicate. Given to
  148.  * one of the printf functions and expects two arguments: the name of the
  149.  * local host and the display number we're using.
  150.  */
  151. #define    DEVICE_TEMPLATE    "/hosts/%s/X%s"
  152.  
  153. #define REASONABLE_TIME        5
  154. #define OUT_BUF_SIZE        2048
  155. #define IN_BUF_SIZE        2048
  156.  
  157. /*
  158.  * The private data maintained for a pseudo-device client
  159.  */
  160. typedef struct {
  161.     int                  streamID;   /* Server stream over which we get the
  162.                      * buffer pointers */
  163.     ClientPtr          client;        /* Client for which this is */
  164.     int                  state;
  165. #define PDEV_REQ_EMPTY            0x0002    /* Request buffer is empty */
  166. #define PDEV_READ_EMPTY            0x0004     /* Read buffer is empty */
  167. #define PDEV_COLLECTING            0x0008    /* Collecting broken X request */
  168. #define PDEV_COLLECTING_HEADER    0x0010    /* Collecting broken X header */
  169.  
  170.     /*
  171.      * Request (inBuf) and read-ahead (outBuf) buffers
  172.      */
  173.     char            outBuf[OUT_BUF_SIZE];
  174.     char              *outPtr;    /* Next place to store data */
  175.  
  176.     char              inBuf[IN_BUF_SIZE];
  177.     Pdev_Request    *reqPtr;    /* Address of next request to process */
  178.     char              *inPtr;        /* Position in current request */
  179.  
  180.     Pdev_BufPtrs      curPtrs;    /* Current pointers for the two buffers */
  181.  
  182.     /*
  183.      * Overflow. If the outBuf fills up, we copy the output data into
  184.      * 'overflow' and copy as much down as possible when the kernel has
  185.      * emptied outBuf.
  186.      *
  187.      * If an X request comes in that is broken across two PDEV_WRITE requests,
  188.      * we allocate enough room to hold it and point bigReq at it, then copy
  189.      * data from inBuf, as it becomes available, into bigReq until the
  190.      * request is fulfilled.
  191.      */
  192.     Buffer            overflow;   /* Any output that won't fit in outBuf */
  193.     char              *bigReq;    /* Points to space for any broken request
  194.                      * that is being assembled. NULL if none */
  195.     char              *bigReqPtr; /* Current position in bigReq */
  196.     int                  need;        /* Number of bytes still needed */
  197. } PdevPrivRec, *PdevPrivPtr;
  198.  
  199. static void       PdevCloseClient();
  200. static char       *PdevReadClient();
  201. static int        PdevWriteClient();
  202.  
  203. int              Pdev_Conn;
  204.  
  205. /*-
  206.  *-----------------------------------------------------------------------
  207.  * Pdev_Init --
  208.  *    Initialize pseudo-device connections.
  209.  *
  210.  * Results:
  211.  *    None.
  212.  *
  213.  * Side Effects:
  214.  *    The pseudo-device for this display is opened. The process will
  215.  *    exit if the device cannot be opened.
  216.  *
  217.  *-----------------------------------------------------------------------
  218.  */
  219. void
  220. Pdev_Init(hostname)
  221.     char    *hostname;    /* The name of the local host */
  222. {
  223.     char          deviceName[100];  /* Path to pseudo-device */
  224.     int              oldPermMask;        /* Previous permission mask */
  225.     ReturnStatus  status;
  226.  
  227.     /*
  228.      * Create the pseudo-device, making sure it's readable and writable
  229.      * by everyone.
  230.      */
  231.  
  232.     sprintf (deviceName, DEVICE_TEMPLATE, hostname, display);
  233.     oldPermMask = umask(0);
  234.     status = Fs_Open (deviceName,
  235.         FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_PDEV_MASTER,
  236.         0666, &Pdev_Conn);
  237.     if (status != 0) {
  238.     errno = Compat_MapCode(status);
  239.     Error (deviceName);
  240.     FatalError ("Could not open pseudo-device %s",
  241.         deviceName);
  242.     }
  243.  
  244.     (void) umask(oldPermMask);
  245. }
  246.  
  247. /*-
  248.  *-----------------------------------------------------------------------
  249.  * PdevSetPtrs --
  250.  *    Set our idea of the state of the two buffers. Called when a
  251.  *    Pdev_BufPtrs structure is read from the kernel. If the read-ahead
  252.  *    buffer has been emptied by the kernel and there's overflow waiting
  253.  *    to go, copy it down and inform the kernel of it.
  254.  *
  255.  * Results:
  256.  *    None.
  257.  *
  258.  * Side Effects:
  259.  *    curPtrs is altered.
  260.  *
  261.  *-----------------------------------------------------------------------
  262.  */
  263. static void
  264. PdevSetPtrs(pdevPriv, bufPtrs)
  265.     PdevPrivPtr    pdevPriv;
  266.     Pdev_BufPtrs      *bufPtrs;
  267. {
  268.     if (DBG(PDEV)) {
  269.     ErrorF("SetPtrs(%d): req %d:%d read %d:%d\n",
  270.            pdevPriv->client ? pdevPriv->client->index : -1,
  271.            bufPtrs->requestFirstByte,
  272.            bufPtrs->requestLastByte,
  273.            bufPtrs->readFirstByte,
  274.            bufPtrs->readLastByte);
  275.     }
  276.  
  277.     /*
  278.      * First update the extent of the request buffer.
  279.      */
  280.     pdevPriv->curPtrs.requestLastByte = bufPtrs->requestLastByte;
  281.     if ((bufPtrs->requestLastByte != -1)  &&
  282.     (pdevPriv->state & PDEV_REQ_EMPTY)) {
  283.         /*
  284.          * We only pay attention to the requestFirstByte if going from
  285.          * an empty to a non-empty buffer, since we think we know where
  286.          * the first request byte actually is.
  287.          */
  288.         pdevPriv->curPtrs.requestFirstByte = bufPtrs->requestFirstByte;
  289.         pdevPriv->reqPtr =
  290.         (Pdev_Request *)&pdevPriv->inBuf[bufPtrs->requestFirstByte];
  291.         pdevPriv->inPtr = (char *)NULL;
  292.         pdevPriv->state &= ~PDEV_REQ_EMPTY;
  293.     }
  294.  
  295.     /*
  296.      * Then the extent of the read buffer.
  297.      */
  298.     pdevPriv->curPtrs.readFirstByte = bufPtrs->readFirstByte;
  299.     if (bufPtrs->readFirstByte == -1) {
  300.     int   numBytes;
  301.  
  302.     pdevPriv->state |= PDEV_READ_EMPTY;
  303.     pdevPriv->outPtr = pdevPriv->outBuf;
  304.  
  305.     numBytes = Buf_Size(pdevPriv->overflow);
  306.     if (numBytes > OUT_BUF_SIZE) {
  307.         numBytes = OUT_BUF_SIZE;
  308.     }
  309.     if (numBytes != 0) {
  310.         /*
  311.          * Copy as much overflow data into the output buffer as possible.
  312.          * The number of bytes actually copied is left in numBytes.
  313.          * pdevPriv->outPtr is set to point to the next place to store
  314.          * data in the buffer.
  315.          */
  316.         numBytes = Buf_GetBytes(pdevPriv->overflow, numBytes,
  317.                     (Byte *)pdevPriv->outBuf);
  318.         pdevPriv->outPtr = &pdevPriv->outBuf[numBytes];
  319.  
  320.         if (numBytes != 0) {
  321.         /*
  322.          * If bytes actually copied, the buffer is no longer empty.
  323.          * Adjust the pointers and inform the kernel of the existence
  324.          * of the data.
  325.          */
  326.         pdevPriv->state &= ~PDEV_READ_EMPTY;
  327.         pdevPriv->curPtrs.readFirstByte = 0;
  328.         pdevPriv->curPtrs.readLastByte = numBytes - 1;
  329.         (void)Fs_IOControl (pdevPriv->streamID,
  330.                     IOC_PDEV_SET_PTRS,
  331.                     sizeof(pdevPriv->curPtrs),
  332.                     (Address)&pdevPriv->curPtrs,
  333.                     0,
  334.                     (Address)NULL);
  335.         }
  336.     } else {
  337.         /*
  338.          * Need to make this -1 so PdevWriteClient works correctly
  339.          * (it adds the number of bytes written to readLastByte without
  340.          * checking its value)
  341.          */
  342.         pdevPriv->curPtrs.readLastByte = -1;
  343.     }
  344.     }
  345. }
  346.     
  347. /*-
  348.  *-----------------------------------------------------------------------
  349.  * PdevRequestHandled --
  350.  *    Tell the kernel that we have handled the request at
  351.  *    pdevPriv->reqPtr and update our own idea of the request buffer.
  352.  *
  353.  * Results:
  354.  *    None.
  355.  *
  356.  * Side Effects:
  357.  *    curPtrs.requestFirstByte is altered, inPtr is NULLed, the
  358.  *    PDEV_REQ_EMPTY flag will be set if the buffer is now empty.
  359.  *
  360.  *-----------------------------------------------------------------------
  361.  */
  362. static void
  363. PdevRequestHandled(pdevPriv)
  364.     PdevPrivPtr    pdevPriv;
  365. {
  366.     ReturnStatus status;
  367.  
  368.     pdevPriv->inPtr = (char *)NULL;
  369.     pdevPriv->curPtrs.requestFirstByte += pdevPriv->reqPtr->hdr.messageSize;
  370.     pdevPriv->reqPtr =
  371.     (Pdev_Request *)&pdevPriv->inBuf[pdevPriv->curPtrs.requestFirstByte];
  372.  
  373.     if (pdevPriv->curPtrs.requestFirstByte >
  374.     pdevPriv->curPtrs.requestLastByte) {
  375.         pdevPriv->state |= PDEV_REQ_EMPTY;
  376.     }
  377.  
  378.     if (DBG(PDEV)) {
  379.     ErrorF("RequestHandled(%d): req %d:%d read %d:%d\n",
  380.            pdevPriv->client ? pdevPriv->client->index : -1,
  381.            pdevPriv->curPtrs.requestFirstByte,
  382.            pdevPriv->curPtrs.requestLastByte,
  383.            pdevPriv->curPtrs.readFirstByte,
  384.            pdevPriv->curPtrs.readLastByte);
  385.     }
  386.  
  387.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  388.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  389.         0, (Address) NULL);
  390.     if (status != 0) {
  391.     errno = Compat_MapCode(status);
  392.     if (DBG(PDEV)) {
  393.         Error("RequestHandled: SET_PTRS");
  394.     }
  395.     }
  396.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  397.     pdevPriv->curPtrs.requestFirstByte =
  398.         pdevPriv->curPtrs.requestLastByte = -1;
  399.     }
  400. }
  401.  
  402. /*-
  403.  *-----------------------------------------------------------------------
  404.  * PdevWaitForReadable --
  405.  *    Wait for a connection to become readable, but only wait a
  406.  *    reasonable amount of time.
  407.  *
  408.  * Results:
  409.  *    Returns 0 if successful, -1 if an error occurs or no
  410.  *    files were readable.
  411.  *
  412.  * Side Effects:
  413.  *    The curPtrs field of the connection is updated.
  414.  *
  415.  *-----------------------------------------------------------------------
  416.  */
  417. static ReturnStatus
  418. PdevWaitForReadable (pdevPriv, selMask)
  419.     PdevPrivPtr    pdevPriv;   /* Connection to read */
  420.     int                  *selMask;   /* Pre-allocated select mask (zeroed) */
  421. {
  422.     Pdev_BufPtrs      bufPtrs;    /* New buffer pointers for stream */
  423.     struct timeval      timeout;    /* Timeout interval for select */
  424.     int                  numReady;   /* Number of ready streams */
  425.     int                  numBytes;   /* Number of bytes read */
  426.     
  427.     Bit_Set (pdevPriv->streamID, selMask);
  428.     timeout.tv_sec = REASONABLE_TIME;
  429.     timeout.tv_usec = 0;
  430.  
  431.     numReady = select(pdevPriv->streamID+1, selMask, (int *) 0, (int *)0,
  432.         &timeout);
  433.     if (numReady < 1) {
  434.     return -1;
  435.     }
  436.  
  437.     numBytes = read(pdevPriv->streamID, (char *) &bufPtrs, sizeof(bufPtrs));
  438.     if (numBytes == -1) {
  439.     if (DBG(PDEV)) {
  440.         Error ("PdevWaitForReadable");
  441.     }
  442.     return (-1);
  443.     }
  444.     if (bufPtrs.magic != PDEV_BUF_PTR_MAGIC) {
  445.     if (DBG(PDEV)) {
  446.         ErrorF ("Buffer magic numbers don't match\n");
  447.     }
  448.     return (-1);
  449.     }
  450.     PdevSetPtrs(pdevPriv, &bufPtrs);
  451.     return (0);
  452. }
  453.  
  454. /*-
  455.  *-----------------------------------------------------------------------
  456.  * PdevConnFail --
  457.  *    Inform a client that it has been denied access.
  458.  *
  459.  * Results:
  460.  *    None.
  461.  *
  462.  * Side Effects:
  463.  *    None.
  464.  *
  465.  *-----------------------------------------------------------------------
  466.  */
  467. static void
  468. PdevConnFail (pdevPriv, swapped, reason)
  469.     PdevPrivPtr    pdevPriv;       /* Failed connection */
  470.     Bool              swapped;        /* TRUE if client is byte-swapped */
  471.     char              *reason;        /* Reason for failure */
  472. {
  473.     int                  *selMask;       /* Mask for selecting on stream */
  474.     struct timeval      timeout;        /* Timeout for select */
  475.     struct timeval      *pTimeOut;
  476.     int                  numReady;       /* Number of streams from select*/
  477.     int                  numBytes;       /* Number of bytes read/written */
  478.     int                  length;            /* Length of reason */
  479.     xConnSetupPrefix    *c;             /* Pointer to returned structure in
  480.                      * read-ahead buffer */
  481.     Pdev_BufPtrs      bufPtrs;        /* New pointers for buffer */
  482.  
  483.  
  484.     if (reason == (char *)NULL) {
  485.     length = 0;
  486.     } else {
  487.     length = strlen (reason);
  488.     }
  489.  
  490.     c = (xConnSetupPrefix *)pdevPriv->outBuf;
  491.     c->success = xFalse;
  492.     c->lengthReason = length;
  493.     c->length = (length + 3) >> 2;
  494.  
  495.     pdevPriv->curPtrs.readFirstByte = 0;
  496.     pdevPriv->curPtrs.readLastByte =
  497.     sizeof(xConnSetupPrefix) + (c->length << 2);
  498.  
  499.     if (!swapped) {
  500.     c->majorVersion = X_PROTOCOL;
  501.     c->minorVersion = X_PROTOCOL_REVISION;
  502.     } else {
  503.     short      n;
  504.  
  505.     swaps(&c->length, n);
  506.     c->majorVersion = lswaps(X_PROTOCOL);
  507.     c->minorVersion = lswaps(X_PROTOCOL_REVISION);
  508.     }
  509.     
  510.     strcpy((char *)&c[1], reason);
  511.  
  512.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  513.              sizeof(pdevPriv->curPtrs),
  514.              (Address)&pdevPriv->curPtrs,
  515.              0, (Address)NULL) != 0) {
  516.              return;
  517.     }
  518.     
  519.     Bit_Alloc (pdevPriv->streamID+1, selMask);
  520.  
  521.     timeout.tv_sec = REASONABLE_TIME;
  522.     timeout.tv_usec = 0;
  523.     if (DBG(PDEV)) {
  524.     pTimeOut = (struct timeval *)0;
  525.     } else {
  526.     pTimeOut = &timeout;
  527.     }
  528.     
  529.     /*
  530.      * We give the client a REASONABLE_TIME to read the failure structure
  531.      * and message. If it doesn't read it in that time, it loses. When the
  532.      * read-ahead buffer is empty, the client has read the info.
  533.      */
  534.     do {
  535.     Bit_Set (pdevPriv->streamID, selMask);
  536.     numReady = select(pdevPriv->streamID+1, selMask, (int *)0, (int *)0,
  537.         pTimeOut);
  538.     if (numReady < 1) {
  539.         if (DBG(PDEV)) {
  540.         ErrorF("PdevConnFail: didn't read in reasonable time\n");
  541.         }
  542.         break;
  543.     }
  544.     numBytes = read(pdevPriv->streamID, (char *) &bufPtrs,
  545.         sizeof(bufPtrs));
  546.     if ((numBytes != sizeof(bufPtrs))
  547.         || (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  548.         break;
  549.     }
  550.     if (bufPtrs.readFirstByte == -1) {
  551.         break;
  552.     } else {
  553.         PdevSetPtrs(pdevPriv, &bufPtrs);
  554.         while (!(pdevPriv->state & PDEV_REQ_EMPTY)) {
  555.         if (pdevPriv->reqPtr->hdr.operation == PDEV_CLOSE) {
  556.             /*
  557.              * If we get a close message before the data are all read,
  558.              * just allow the client to go away gracefully -- reply to
  559.              * the close and get the h*** out of here.
  560.              */
  561.             Pdev_Reply    reply;
  562.  
  563.             reply.magic = PDEV_REPLY_MAGIC;
  564.             reply.status = SUCCESS;
  565.             reply.selectBits = 0;
  566.             reply.replySize = 0;
  567.             reply.replyBuf = (Address)NULL;
  568.             reply.signal = 0;
  569.             reply.code = 0;
  570.             (void)Fs_IOControl(pdevPriv->streamID,
  571.                        IOC_PDEV_REPLY,
  572.                        sizeof(reply), (Address)&reply,
  573.                        0, (Address)NULL);
  574.             PdevRequestHandled(pdevPriv);
  575.             goto done;
  576.         }
  577.         /*
  578.          * Anything else we just drop on the floor
  579.          */
  580.         PdevRequestHandled(pdevPriv);
  581.         }
  582.     }
  583.     } while (!pTimeOut || (pTimeOut->tv_sec || pTimeOut->tv_usec));
  584.  
  585. done:
  586.     Bit_Free (selMask);
  587. }
  588.  
  589. /*-
  590.  *-----------------------------------------------------------------------
  591.  * Pdev_EstablishNewConnections --
  592.  *    Accept connections from new clients. 
  593.  *
  594.  * Results:
  595.  *    None returned. pNewClients and *pNumNew are filled in.
  596.  *
  597.  * Side Effects:
  598.  *    AllClientsMask and AllStreamsMask are altered. Fields in the
  599.  *    private structure for the new clients are filled and several
  600.  *    private structures are created.
  601.  *
  602.  *-----------------------------------------------------------------------
  603.  */
  604. void
  605. Pdev_EstablishNewConnections (pNewClients, pNumNew)
  606.     ClientPtr            *pNewClients;    /* Array to fill in */
  607.     int                  *pNumNew;     /* Number of new connections
  608.                      * established */
  609. {
  610.     Pdev_Notify          note;            /* Notification of new stream */
  611.     PdevPrivPtr    pdevPriv;           /* New private information for us */
  612.     ClntPrivPtr          pPriv;            /* New private information for client */
  613.     ClientPtr          client;            /* New client */
  614.     Pdev_Request    *pdevReq;       /* Pointer to current request */
  615.     Pdev_Reply     openReply;          /* Reply to open request */
  616.     Pdev_SetBufArgs    bufArgs;        /* Structure to set r/w buffers */
  617.     int                  numBytes;       /* Number of bytes read */
  618.     xConnClientPrefix    *xccp;            /* Client's description of itself */
  619.     Boolean              swapped;        /* Set TRUE if client is byte-swapped.
  620.                      * FALSE otherwise. */
  621.     Boolean           writeBehind;    /* For IOC_PDEV_WRITE_BEHIND */
  622.  
  623.     pNewClients += *pNumNew;
  624.     writeBehind = TRUE;            /* Turn on write-behind */
  625.  
  626.     while (1) {
  627.     numBytes = read(Pdev_Conn, (char *) ¬e, sizeof(note));
  628.     if ((numBytes != sizeof(note)) || (note.magic != PDEV_NOTIFY_MAGIC)) {
  629.         return;
  630.     }
  631.  
  632.     Ioc_SetBits(note.newStreamID, IOC_NON_BLOCKING);
  633.     
  634.     pdevPriv = (PdevPrivPtr) malloc(sizeof(PdevPrivRec));
  635.     pdevPriv->streamID =                     note.newStreamID;
  636.     pdevPriv->client =                      NullClient;
  637.     pdevPriv->state =                       PDEV_REQ_EMPTY|PDEV_READ_EMPTY;
  638.     pdevPriv->curPtrs.magic =               PDEV_BUF_PTR_MAGIC;
  639.     pdevPriv->curPtrs.requestFirstByte =    -1;
  640.     pdevPriv->curPtrs.requestLastByte =     -1;
  641.     pdevPriv->curPtrs.readFirstByte =       -1;
  642.     pdevPriv->curPtrs.readLastByte =        -1;
  643.     pdevPriv->inPtr =                       (char *)NULL;
  644.     pdevPriv->outPtr =                      pdevPriv->outBuf;
  645.     pdevPriv->overflow =                    Buf_Init(0);
  646.     pdevPriv->bigReq =                      (char *)NULL;
  647.     pdevPriv->bigReqPtr =                    (char *)NULL;
  648.  
  649.     pPriv = (ClntPrivPtr) malloc(sizeof(ClntPrivRec));
  650.     pPriv->readProc =                       PdevReadClient;
  651.     pPriv->writeProc =                      PdevWriteClient;
  652.     pPriv->closeProc =                      PdevCloseClient;
  653.     pPriv->mask =                            (int *)0;
  654.     pPriv->ready =                            (int *)0;
  655.     pPriv->maskWidth =                      0;
  656.     pPriv->devicePrivate =                     (pointer)pdevPriv;
  657.     
  658.     bufArgs.requestBufAddr = pdevPriv->inBuf;
  659.     bufArgs.requestBufSize = IN_BUF_SIZE;
  660.     bufArgs.readBufAddr = pdevPriv->outBuf;
  661.     bufArgs.readBufSize = OUT_BUF_SIZE;
  662.  
  663.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_BUF,
  664.                sizeof(bufArgs), (Address)&bufArgs,
  665.                0, (Address)NULL);
  666.     (void)Fs_IOControl(pdevPriv->streamID, IOC_PDEV_WRITE_BEHIND,
  667.                sizeof(Boolean), (Address) &writeBehind,
  668.                0, (Address)NULL);
  669.  
  670.     ExpandMasks (pPriv, pdevPriv->streamID);
  671.  
  672.     /*
  673.      * Wait for and handle the OPEN request. If the request comes from
  674.      * an un-authorized source, we return a status of FS_NO_ACCESS. If
  675.      * there's an error, we close the stream and free everything.
  676.      */
  677.     if ((PdevWaitForReadable(pdevPriv, pPriv->ready) != 0) ||
  678.         (pdevPriv->reqPtr->hdr.operation != PDEV_OPEN)) {
  679.         (void) close(pdevPriv->streamID);
  680.         free((char *)pdevPriv);
  681.         free((char *)pPriv);
  682.         continue;
  683.     }
  684.     pdevReq = pdevPriv->reqPtr;
  685.  
  686.     openReply.magic =       PDEV_REPLY_MAGIC;
  687.     openReply.selectBits =     FS_WRITABLE | FS_READABLE;
  688.     openReply.replySize =    0;
  689.     openReply.replyBuf =    (Address)NULL;
  690.     openReply.signal = 0;
  691.     openReply.code = 0;
  692.  
  693.     if (InvalidHost(FamilySprite, pdevReq->param.open.uid,
  694.             pdevReq->param.open.hostID)) {
  695.         openReply.status = FS_NO_ACCESS;
  696.         (void) Fs_IOControl(pdevPriv->streamID, IOC_PDEV_REPLY,
  697.                 sizeof(openReply), (Address)&openReply,
  698.                 0, (Address)NULL);
  699.         
  700.         (void) close(pdevPriv->streamID);
  701.         free((char *)pdevPriv);
  702.         free((char *)pPriv);
  703.         continue;
  704.     } else {
  705.         openReply.status = SUCCESS;
  706.         (void) Fs_IOControl(pdevPriv->streamID, IOC_PDEV_REPLY,
  707.                 sizeof(openReply), (Address)&openReply,
  708.                 0, (Address)NULL);
  709.         
  710.     }
  711.  
  712.     PdevRequestHandled(pdevPriv);
  713.  
  714.     /*
  715.      * Once the OPEN operation has been received, we must wait for the
  716.      * client to write an xConnClientPrefix on the device. Since the
  717.      * Sprite Xlib doesn't pass any extra authorization string junk,
  718.      * we only need to read the prefix.
  719.      */
  720.  
  721.     if (PdevWaitForReadable(pdevPriv, pPriv->ready) != 0) {
  722.         (void) close(pdevPriv->streamID);
  723.         free((char *)pdevPriv);
  724.         free((char *)pPriv);
  725.         continue;
  726.     }
  727.     pdevReq = pdevPriv->reqPtr;
  728.  
  729.     if (pdevReq->hdr.operation == PDEV_WRITE_ASYNC) {
  730.         pdevReq->hdr.operation = PDEV_WRITE;
  731.     }
  732.     if ((pdevReq->hdr.magic != PDEV_REQUEST_MAGIC) ||
  733.         (pdevReq->hdr.operation != PDEV_WRITE) ||
  734.         (pdevReq->hdr.requestSize < sizeof(xConnClientPrefix))) {
  735.         (void) close(pdevPriv->streamID);
  736.         free((char *)pdevPriv);
  737.         free((char *)pPriv);
  738.         continue;
  739.     }
  740.  
  741.     xccp = (xConnClientPrefix *)&pdevReq[1];
  742.     if (xccp->byteOrder != whichByteIsFirst) {
  743.         SwapConnClientPrefix (xccp);
  744.         swapped = TRUE;
  745.     } else {
  746.         swapped = FALSE;
  747.     }
  748.  
  749.     if ((xccp->majorVersion != X_PROTOCOL) ||
  750.         (xccp->minorVersion != X_PROTOCOL_REVISION)) {
  751.         PdevRequestHandled(pdevPriv);
  752.         PdevConnFail(pdevPriv, swapped, "Protocol version mismatch");
  753.         (void) close(pdevPriv->streamID);
  754.         free((char *)pdevPriv);
  755.         free((char *)pPriv);
  756.         continue;
  757.     }
  758.     if ((xccp->nbytesAuthProto != 0) || (xccp->nbytesAuthString != 0)) {
  759.         PdevRequestHandled(pdevPriv);
  760.         PdevConnFail(pdevPriv, swapped,
  761.                 "Can't handle authorization strings");
  762.         (void) close(pdevPriv->streamID);
  763.         free((char *)pdevPriv);
  764.         free((char *)pPriv);
  765.         continue;
  766.     }
  767.  
  768.     client = (ClientPtr)NextAvailableClient();
  769.     if (client == NullClient) {
  770.         PdevRequestHandled(pdevPriv);
  771.         PdevConnFail(pdevPriv, swapped, "Too many clients");
  772.         (void) close(pdevPriv->streamID);
  773.         free((char *)pdevPriv);
  774.         free((char *)pPriv);
  775.         continue;
  776.     } else {
  777.         pdevPriv->client = client;
  778.         client->osPrivate = (pointer)pPriv;
  779.         client->swapped = swapped;
  780.     }
  781.     
  782.     PdevRequestHandled(pdevPriv);
  783.  
  784.     if (DBG(PDEV) || DBG(CONN)) {
  785.         ErrorF ("New Pdev connection: client %d (newID = %d)\n",
  786.             client->index, pdevPriv->streamID);
  787.     }
  788.         
  789.     if ((pdevPriv->state & PDEV_REQ_EMPTY) == 0) {
  790.         /*
  791.          * If there's still stuff left in the request buffer (beyond
  792.          * the initial open request), mark the stream as having input...
  793.          */
  794.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  795.     }
  796.     
  797.     *pNewClients = client;
  798.     pNewClients++;
  799.     (*pNumNew)++;
  800.  
  801.     /*
  802.      * If we're only listening to one client, add the new client's
  803.      * stream to the saved AllClients and AllStreams masks so it is
  804.      * included when the grab is released. Otherwise, we can just
  805.      * add the stream to the regular AllClients and AllStreams
  806.      * masks.
  807.      */
  808.     if (GrabDone) {
  809.         Bit_Set (pdevPriv->streamID, SavedAllClientsMask);
  810.         Bit_Set (pdevPriv->streamID, SavedAllStreamsMask);
  811.     } else {
  812.         Bit_Set (pdevPriv->streamID, AllClientsMask);
  813.         Bit_Set (pdevPriv->streamID, AllStreamsMask);
  814.     }
  815.     }
  816. }
  817.     
  818. /*-
  819.  *-----------------------------------------------------------------------
  820.  * PdevCloseClient --
  821.  *    Some client is being booted. Free up our part of its connection
  822.  *    resources. XXX: Maybe we should wait for the read-ahead buffer to
  823.  *    drain?
  824.  *
  825.  * Results:
  826.  *    None.
  827.  *
  828.  * Side Effects:
  829.  *    The pseudo-device stream is closed and the private data freed
  830.  *    The stream is removed from these masks:
  831.  *        AllStreamsMask, SavedAllStreamsMask, AllClientsMask,
  832.  *        SavedAllClientsMask, ClientsWithInputMask
  833.  *
  834.  *-----------------------------------------------------------------------
  835.  */
  836. static void
  837. PdevCloseClient (pPriv)
  838.     ClntPrivPtr      pPriv;        /* Private data for client whose connection
  839.                  * should be closed */
  840. {
  841.     register PdevPrivPtr pdevPriv;
  842.     register int          streamID;
  843.  
  844.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  845.     
  846.     streamID = pdevPriv->streamID;
  847.     close(streamID);
  848.     Bit_Clear(streamID, AllStreamsMask);
  849.     Bit_Clear(streamID, SavedAllStreamsMask);
  850.     Bit_Clear(streamID, AllClientsMask);
  851.     Bit_Clear(streamID, SavedAllClientsMask);
  852.     Bit_Clear(streamID, ClientsWithInputMask);
  853.     Buf_Destroy(pdevPriv->overflow, TRUE);
  854.  
  855.     if (pdevPriv->state & PDEV_COLLECTING) {
  856.     free((char *) pdevPriv->bigReq);
  857.     }
  858.         
  859.     free((char *) pdevPriv);
  860. }
  861.  
  862. #define request_length(req, cli) \
  863.      (((cli)->swapped?lswaps(((xReq *)(req))->length):\
  864.       ((xReq *)(req))->length) << 2)
  865.  
  866.  
  867. /*-
  868.  *-----------------------------------------------------------------------
  869.  * PdevReadClient --
  870.  *    Return one request from the given client. If the client is being
  871.  *    naughty, we call ConnectionClosed to close the thing down.
  872.  *    The client will be closed down as well if the stream which acted
  873.  *    up was the only one open for the client. We still return NULL
  874.  *    with status 0 from there, but the client is gone...
  875.  *
  876.  * Results:
  877.  *    The request buffer.
  878.  *
  879.  * Side Effects:
  880.  *    ClientsWithInputMask may be modified.
  881.  *
  882.  *-----------------------------------------------------------------------
  883.  */
  884. /*ARGSUSED*/
  885. static char *
  886. PdevReadClient (pPriv, pStatus, oldbuf)
  887.     ClntPrivPtr          pPriv;        /* Client with input */
  888.     int                  *pStatus;   /* Result of read:
  889.                      *    >0 -- number of bytes in the request
  890.                      *   0  -- not all the request is there
  891.                      *    <0 -- indicates an error */
  892.     char              *oldbuf;    /* The previous buffer */
  893. {
  894.     PdevPrivPtr      pdevPriv;   /* Private data for the client */
  895.     int                  need;        /* Number of bytes needed for the
  896.                      * current request */
  897.     xReq              *reqPtr;    /* Request to give back */
  898.     Pdev_BufPtrs      bufPtrs;    /* New pointers for buffer */
  899.     int                  numBytes;
  900.     Pdev_ReplyData     reply;
  901.  
  902.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  903.  
  904.     Bit_Clear (pdevPriv->streamID, ClientsWithInputMask);
  905.     
  906.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  907.     if (Bit_IsSet(pdevPriv->streamID, pPriv->ready)) {
  908.         /*
  909.          * If the request buffer is empty, we think, then we need to see if
  910.          * the kernel has anything for us. However, we only do the read on
  911.          * the device if we actually got here because selecdt says the
  912.          * stream is ready. This prevents a client from hogging the server
  913.          * in an obnoxious fashion...
  914.          */
  915.         numBytes = read(pdevPriv->streamID, &bufPtrs, sizeof(bufPtrs));
  916.         if (numBytes == -1) {
  917.         if (errno != EWOULDBLOCK) {
  918.             if (DBG(PDEV)) {
  919.             Error("Reading buffer pointers");
  920.             }
  921.             *pStatus = -1;
  922.             return((char *)NULL);
  923.         } else {
  924.             /*
  925.              * Wasn't actually anything to read. Go on to
  926.              * the next client...
  927.              */
  928.             *pStatus = 0;
  929.             SchedYield();
  930.             return ((char *)NULL);
  931.         }
  932.         }
  933.         if ((numBytes != sizeof(bufPtrs)) ||
  934.         (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  935.             if (DBG(PDEV)) {
  936.             ErrorF("Improper data when reading buffer pointers");
  937.             }
  938.             *pStatus = -1;
  939.             return ((char *)NULL);
  940.         }
  941.         PdevSetPtrs(pdevPriv, &bufPtrs);
  942.     }
  943.     if (pdevPriv->state & PDEV_REQ_EMPTY) {
  944.         /*
  945.          * If there are still no requests, there's nothing more to
  946.          * be done. PdevSetPtrs will have copied any overflow
  947.          * to the read-ahead buffer, so...
  948.          */
  949.         *pStatus = 0;
  950.         SchedYield();
  951.         return ((char *)NULL);
  952.     }
  953.     }
  954.  
  955.     Bit_Clear (pdevPriv->streamID, pPriv->ready);
  956.     
  957.     /*
  958.      * Process the requests until we get one that's a WRITE request,
  959.      * then set inPtr to the data for the request and break out
  960.      * of the loop.
  961.      */
  962.     while ((pdevPriv->inPtr == (char *)NULL) &&
  963.        !(pdevPriv->state & PDEV_REQ_EMPTY))
  964.     {
  965.     switch (pdevPriv->reqPtr->hdr.operation) {
  966.         case PDEV_WRITE_ASYNC:
  967.         case PDEV_WRITE:
  968.         if (DBG(PDEV)) {
  969.             ErrorF("client %d: PDEV_WRITE(%d)\n",
  970.                pdevPriv->client->index,
  971.                pdevPriv->reqPtr->hdr.requestSize);
  972.         }
  973.         pdevPriv->inPtr = (char *)&pdevPriv->reqPtr[1];
  974.         break;
  975.         case PDEV_CLOSE:
  976.         /*
  977.          * We like closes. We just return -1 to cause the
  978.          * connection to be aborted.
  979.          */
  980.         if (DBG(PDEV) || DBG(CONN)) {
  981.             ErrorF("client %d: PDEV_CLOSE\n", pdevPriv->client->index);
  982.         }
  983.         reply.magic = PDEV_REPLY_MAGIC;
  984.         reply.status = SUCCESS;
  985.         reply.selectBits = 0;
  986.         reply.replySize = 0;
  987.         reply.replyBuf = (Address)NULL;
  988.         reply.signal = 0;
  989.         reply.code = 0;
  990.         (void)Fs_IOControl(pdevPriv->streamID,
  991.                    IOC_PDEV_REPLY,
  992.                    sizeof(reply), (Address)&reply,
  993.                    0, (Address)NULL);
  994.         PdevRequestHandled(pdevPriv);
  995.         *pStatus = -1;
  996.         return ((char *)NULL);
  997.         case PDEV_IOCTL: {
  998.         /*
  999.          * All this should be unnecessary, but we reply to it
  1000.          * anyway and pretend we know what we're doing when it
  1001.          * comes to the IOC_NUM_READABLE
  1002.          */
  1003.         char    *inBuffer;
  1004.         int    replyBuf;
  1005.         int    command;
  1006.         
  1007.         reply.magic = PDEV_REPLY_MAGIC;
  1008.         reply.status = SUCCESS;
  1009.         reply.selectBits =
  1010.             ((pdevPriv->state & PDEV_READ_EMPTY)?0:FS_READABLE) |
  1011.             FS_WRITABLE;
  1012.         reply.replySize = 0;
  1013.         reply.replyBuf = (Address)&replyBuf;
  1014.         
  1015.         if (pdevPriv->reqPtr->hdr.requestSize) {
  1016.             inBuffer = (char *)&pdevPriv->reqPtr[1];
  1017.         } else {
  1018.             inBuffer = (char *)NULL;
  1019.         }
  1020.         if (DBG(PDEV)) {
  1021.             ErrorF("client %d: PDEV_IOCTL(%x, %d, %x, %d, ...)\n",
  1022.                pdevPriv->client->index,
  1023.                pdevPriv->reqPtr->param.ioctl.command,
  1024.                pdevPriv->reqPtr->hdr.requestSize,
  1025.                inBuffer,
  1026.                pdevPriv->reqPtr->hdr.replySize);
  1027.         }
  1028.         
  1029.         switch (pdevPriv->reqPtr->param.ioctl.command) {
  1030.             case IOC_NUM_READABLE:
  1031.             /*
  1032.              * XXX: This is already handled by the
  1033.              * kernel since it knows how much it has
  1034.              * more accurately than I do.
  1035.              */
  1036.             reply.replySize = sizeof(int);
  1037.             replyBuf = pdevPriv->curPtrs.readLastByte -
  1038.                 pdevPriv->curPtrs.readFirstByte;
  1039.             break;
  1040.             case IOC_SET_BITS:
  1041.             case IOC_SET_FLAGS:
  1042.             break;
  1043.             case IOC_CLEAR_BITS:
  1044.             case IOC_GET_FLAGS:
  1045.             replyBuf = 0;
  1046.             reply.replySize = sizeof(int);
  1047.             break;
  1048.             default:
  1049.             if (DBG(PDEV)) {
  1050.                 ErrorF("Invalid IOCTL %x\n",
  1051.                    pdevPriv->reqPtr->param.ioctl.command);
  1052.             }
  1053.             reply.status = FS_DEVICE_OP_INVALID;
  1054.             break;
  1055.         }
  1056.         reply.signal = 0;
  1057.         reply.code = 0;
  1058.         if (reply.replySize > 0) {
  1059.             *(int *)reply.data = replyBuf;
  1060.             command = IOC_PDEV_SMALL_REPLY;
  1061.         } else {
  1062.             command = IOC_PDEV_REPLY;
  1063.         }
  1064.         (void)Fs_IOControl(pdevPriv->streamID,
  1065.                    command,
  1066.                    sizeof(reply), (Address)&reply,
  1067.                    0, (Address)NULL);
  1068.         PdevRequestHandled(pdevPriv);
  1069.         break;
  1070.         }
  1071.         default:
  1072.         /*
  1073.          * Bad pseudo-device request -- close the beastie down
  1074.          */
  1075.         reply.magic = PDEV_REPLY_MAGIC;
  1076.         reply.status = FS_DEVICE_OP_INVALID;
  1077.         reply.selectBits = 0;
  1078.         reply.replySize = 0;
  1079.         reply.replyBuf = (Address)NULL;
  1080.         reply.signal = 0;
  1081.         reply.code = 0;
  1082.         if (DBG(PDEV)) {
  1083.             ErrorF("Bad new pdev request %d client %d\n",
  1084.                pdevPriv->reqPtr->hdr.operation,
  1085.                pdevPriv->client->index);
  1086.         }
  1087.         (void)Fs_IOControl(pdevPriv->streamID,
  1088.                    IOC_PDEV_REPLY,
  1089.                    sizeof(reply), (Address)&reply,
  1090.                    0, (Address)NULL);
  1091.         PdevRequestHandled(pdevPriv);
  1092.         *pStatus = -1;
  1093.         return ((char *)NULL);
  1094.     }
  1095.     }
  1096.     if (pdevPriv->inPtr == (char *)NULL) {
  1097.     /*
  1098.      * If didn't reach a PDEV_WRITE request, there's nothing more
  1099.      * to do...
  1100.      */
  1101.     Bit_Clear(pdevPriv->streamID, ClientsWithInputMask);
  1102.     SchedYield();
  1103.     *pStatus = 0;
  1104.     return ((char *)NULL);
  1105.     }
  1106.     
  1107.     if (pdevPriv->state & PDEV_COLLECTING) {
  1108.     /*
  1109.      * Collecting an X request that was broken across a WRITE boundary.
  1110.      * bigReqPtr points to the next place to store stuff for the
  1111.      * request, while need contains the number of bytes still needed
  1112.      * to fill the request. bigReq has been allocated to contain
  1113.      * the requisite space.
  1114.      */
  1115.     need = min(pdevPriv->need, pdevPriv->reqPtr->hdr.requestSize);
  1116.     bcopy(pdevPriv->inPtr, pdevPriv->bigReqPtr, need);
  1117.     pdevPriv->bigReqPtr += need;
  1118.     pdevPriv->need -= need;
  1119.     pdevPriv->inPtr += need;
  1120.     if (pdevPriv->need != 0) {
  1121.         PdevRequestHandled(pdevPriv);
  1122.         *pStatus = 0;
  1123.         return ((char *)NULL);
  1124.     } else {
  1125.         pdevPriv->reqPtr->hdr.requestSize -= need;
  1126.         need = request_length(pdevPriv->bigReq, pdevPriv->client);
  1127.         *pStatus = need;
  1128.         pdevPriv->state &= ~PDEV_COLLECTING;
  1129.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  1130.         if (DBG(PDEV)) {
  1131.         ErrorF("XRequest(%d, %d) #%d\n", pdevPriv->client->index,
  1132.                ((xReq *)pdevPriv->bigReq)->reqType,
  1133.                pdevPriv->client->sequence + 1);
  1134.         }
  1135.         return (pdevPriv->bigReq);
  1136.     }
  1137.     } else if (pdevPriv->state & PDEV_COLLECTING_HEADER) {
  1138.     /*
  1139.      * The header for the request was broken across a WRITE boundary.
  1140.      * bigReqPtr points to the place we left off in the header,
  1141.      * while bigReq points to a piece of memory big enough for
  1142.      * an xReq and no more.  Once the entire request header is seen,
  1143.      * we can allocate a large enough buffer for the entire request.
  1144.      */
  1145.     need = min(pdevPriv->need, pdevPriv->reqPtr->hdr.requestSize);
  1146.     bcopy(pdevPriv->inPtr, pdevPriv->bigReqPtr, need);
  1147.     pdevPriv->bigReqPtr += need;
  1148.     pdevPriv->need -= need;
  1149.     pdevPriv->inPtr += need;
  1150.     if (pdevPriv->need != 0) {
  1151.         /*
  1152.          * XXX: Shouldn't happen
  1153.          */
  1154.         PdevRequestHandled(pdevPriv);
  1155.         *pStatus = 0;
  1156.         return ((char *)NULL);
  1157.     } else {
  1158.         /*
  1159.          * We've now gotten a complete header. To keep this simple
  1160.          * we just allocate the needed buffer, copy the header in,
  1161.          * switch to COLLECTING state from COLLECTING_HEADER and
  1162.          * return a blocked read. We'll get called again (very
  1163.          * soon) to fill out the request...
  1164.          */
  1165.         xReq    *xreq;
  1166.  
  1167.         xreq = (xReq *)pdevPriv->bigReq;
  1168.         need = request_length(xreq, pdevPriv->client);
  1169.         pdevPriv->bigReq = malloc((unsigned) need);
  1170.         bcopy(xreq, pdevPriv->bigReq, sizeof(xReq));
  1171.         pdevPriv->bigReqPtr += sizeof(xReq);
  1172.         pdevPriv->need = need - sizeof(xReq);
  1173.         pdevPriv->state ^= PDEV_COLLECTING|PDEV_COLLECTING_HEADER;
  1174.         free((char *) xreq);
  1175.         *pStatus = 0;
  1176.         return ((char *)NULL);
  1177.     }
  1178.     }
  1179.     if (pdevPriv->bigReq != (char *)NULL) {
  1180.     /*
  1181.      * If we're not collecting anything and there's something
  1182.      * pointed to by bigReq, it must be old and should be
  1183.      * deallocated.
  1184.      */
  1185.     free((char *) pdevPriv->bigReq);
  1186.     pdevPriv->bigReq = (char *)NULL;
  1187.     }
  1188.     if (pdevPriv->reqPtr->hdr.requestSize < sizeof(xReq)) {
  1189.     if (pdevPriv->reqPtr->hdr.requestSize != 0) {
  1190.         /*
  1191.          * Only go into the COLLECTING_HEADER state if there are
  1192.          * data bytes left in the request (i.e. it's really a broken
  1193.          * header, not just an exhausted WRITE request).
  1194.          */
  1195.         pdevPriv->state |= PDEV_COLLECTING_HEADER;
  1196.         pdevPriv->bigReq = (char *) malloc(sizeof(xReq));
  1197.         bcopy(pdevPriv->inPtr, pdevPriv->bigReq,
  1198.             pdevPriv->reqPtr->hdr.requestSize);
  1199.         pdevPriv->bigReqPtr =
  1200.         pdevPriv->bigReq + pdevPriv->reqPtr->hdr.requestSize;
  1201.         pdevPriv->need = sizeof(xReq) - pdevPriv->reqPtr->hdr.requestSize;
  1202.     }
  1203.     PdevRequestHandled(pdevPriv);
  1204.     *pStatus = 0;
  1205.     return ((char *)NULL);
  1206.     } else {
  1207.     /*
  1208.      * Can actually figure out the size of the request. Store it
  1209.      * in 'need'
  1210.      */
  1211.     need = request_length (pdevPriv->inPtr, pdevPriv->client);
  1212.     
  1213.     if (need > pdevPriv->reqPtr->hdr.requestSize) {
  1214.         /*
  1215.          * The X request didn't fit in PDEV_WRITE request, so
  1216.          * we mark the stream as collecting a (big) request, copy
  1217.          * in whatever data we have and return a blocked read status.
  1218.          * Note we DO NOT yield the server since there may be another
  1219.          * write request pending.
  1220.          */
  1221.         pdevPriv->state |= PDEV_COLLECTING;
  1222.         pdevPriv->bigReq = (char *) malloc((unsigned) need);
  1223.         bcopy(pdevPriv->inPtr, pdevPriv->bigReq,
  1224.             pdevPriv->reqPtr->hdr.requestSize);
  1225.         pdevPriv->bigReqPtr =
  1226.         pdevPriv->bigReq + pdevPriv->reqPtr->hdr.requestSize;
  1227.         pdevPriv->need = need - pdevPriv->reqPtr->hdr.requestSize;
  1228.         PdevRequestHandled(pdevPriv);
  1229.         *pStatus = 0;
  1230.         return ((char *)NULL);
  1231.     } else {
  1232.         reqPtr = (xReq *)pdevPriv->inPtr;
  1233.         pdevPriv->inPtr += need;
  1234.         pdevPriv->reqPtr->hdr.requestSize -= need;
  1235.         *pStatus = need;
  1236.         Bit_Set(pdevPriv->streamID, ClientsWithInputMask);
  1237.         if (DBG(PDEV)) {
  1238.         ErrorF("XRequest(%d, %d) #%d\n", pdevPriv->client->index,
  1239.                reqPtr->reqType, pdevPriv->client->sequence+1);
  1240.         }
  1241.         return ((char *)reqPtr);
  1242.     }
  1243.     }
  1244. }
  1245.  
  1246. /*-
  1247.  *-----------------------------------------------------------------------
  1248.  * PdevWriteClient --
  1249.  *    Write data to the client. Data are copied into the read buffer
  1250.  *    as much as possible. Data that cannot fit in the read buffer are
  1251.  *    placed in the overflow buffer until the kernel catches up with us,
  1252.  *    at which point the data are copied back down to the read buffer.
  1253.  *    Output packets may be broken at arbitrary points and all
  1254.  *    transmissions are rounded to be a multiple of 32 bits long. Because
  1255.  *    of this, if the entire packet fits into the read buffer, the
  1256.  *    pad bytes do too.
  1257.  *
  1258.  * Results:
  1259.  *    Number of bytes written.
  1260.  *
  1261.  * Side Effects:
  1262.  *    The data bytes are stuffed into the buffer for the client, awaiting
  1263.  *    a read request from the client.
  1264.  *
  1265.  *-----------------------------------------------------------------------
  1266.  */
  1267. static int
  1268. PdevWriteClient (pPriv, numBytes, xRepPtr)
  1269.     ClntPrivPtr      pPriv;        /* Client to receive the data */
  1270.     int              numBytes;     /* Number of bytes (unrounded) */
  1271.     Address          xRepPtr;     /* The data bytes */
  1272. {
  1273.     int                      rndNumBytes;    /* Number of bytes, rounded to a
  1274.                          * longword */
  1275.     int                      pad = 0;        /* Padding bytes */
  1276.     register int          padding;        /* Number of bytes needed */
  1277.     register PdevPrivPtr    pdevPriv;        /* Data private to client */
  1278.     ReturnStatus        status;
  1279.  
  1280.     rndNumBytes = (numBytes + 3) & ~3;
  1281.  
  1282.     pdevPriv = (PdevPrivPtr) pPriv->devicePrivate;
  1283.     
  1284.     
  1285.     padding = rndNumBytes - numBytes;
  1286.  
  1287.     if (pdevPriv->curPtrs.readLastByte == (OUT_BUF_SIZE - 1)) {
  1288.     /*
  1289.      * Output buffer is full -- must copy data to overflow buffer
  1290.      */
  1291.     if (DBG(PDEV)) {
  1292.         ErrorF("WriteClient(%d): overflow -- ", pdevPriv->client->index);
  1293.     }
  1294.     Buf_AddBytes(pdevPriv->overflow, numBytes, (Byte *)xRepPtr);
  1295.     if (padding != 0) {
  1296.         Buf_AddBytes(pdevPriv->overflow, padding, (Byte *)&pad);
  1297.     }
  1298.     } else {
  1299.     int       numWrite;
  1300.  
  1301.     numWrite = min(numBytes,OUT_BUF_SIZE - pdevPriv->curPtrs.readLastByte);
  1302.     bcopy((char *) xRepPtr, (char *) pdevPriv->outPtr, numWrite);
  1303.     numBytes -= numWrite;
  1304.  
  1305.     /*
  1306.      * Update the output pointers. Note that since readLastByte starts
  1307.      * at -1, adding numWrite will point to the last valid byte of data
  1308.      * in the buffer...
  1309.      */
  1310.     pdevPriv->curPtrs.readLastByte += numWrite;
  1311.     pdevPriv->outPtr += numWrite;
  1312.     
  1313.     if (numBytes != 0) {
  1314.         /*
  1315.          * Didn't manage to fit the entire request into the read-ahead
  1316.          * buffer. Copy excess to overflow.
  1317.          */
  1318.         Buf_AddBytes(pdevPriv->overflow,
  1319.              numBytes,
  1320.              ((Byte *)xRepPtr) + numWrite);
  1321.         if (padding != 0) {
  1322.         Buf_AddBytes(pdevPriv->overflow,
  1323.                  padding,
  1324.                  (Byte *)&pad);
  1325.         }
  1326.     } else if (padding != 0) {
  1327.         /*
  1328.          * Because the buffer is a multiple of 32-bits long, any rounding
  1329.          * that needs to be done is guaranteed to fit if the unrounded
  1330.          * packet fit.
  1331.          */
  1332.         bcopy((char *) &pad, pdevPriv->outPtr, padding);
  1333.         pdevPriv->curPtrs.readLastByte += padding;
  1334.         pdevPriv->outPtr += padding;
  1335.     }
  1336.  
  1337.     /*
  1338.      * Inform kernel of new read buffer extents
  1339.      */
  1340.     status = Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1341.         sizeof(pdevPriv->curPtrs), (Address) &pdevPriv->curPtrs,
  1342.         0, (Address) NULL);
  1343.     if (status != 0) {
  1344.         errno = Compat_MapCode(status);
  1345.         if (DBG(PDEV)) {
  1346.         Error("WriteClient: SET_PTRS");
  1347.         }
  1348.     }
  1349.     if (DBG(PDEV)) {
  1350.         ErrorF("WriteClient(%d): req %d:%d read %d:%d ",
  1351.            pdevPriv->client->index,
  1352.            pdevPriv->curPtrs.requestFirstByte,
  1353.            pdevPriv->curPtrs.requestLastByte,
  1354.            pdevPriv->curPtrs.readFirstByte,
  1355.            pdevPriv->curPtrs.readLastByte);
  1356.         
  1357.         switch (((xReply *)xRepPtr)->generic.type) {
  1358.         case X_Reply:
  1359.             ErrorF("Reply to %d\n",
  1360.                ((xReply *)xRepPtr)->generic.sequenceNumber);
  1361.             break;
  1362.         case X_Error:
  1363.             ErrorF("Error for %d\n",
  1364.                ((xReply *)xRepPtr)->generic.sequenceNumber);
  1365.             break;
  1366.         case KeyPress: ErrorF("KeyPress event\n"); break;
  1367.         case KeyRelease: ErrorF("KeyRelease event\n"); break;
  1368.         case ButtonPress: ErrorF("ButtonPress event\n"); break;
  1369.         case ButtonRelease: ErrorF("ButtonRelease event\n"); break;
  1370.         case MotionNotify: ErrorF("MotionNotify event\n"); break;
  1371.         case EnterNotify: ErrorF("EnterNotify event\n"); break;
  1372.         case LeaveNotify: ErrorF("LeaveNotify event\n"); break;
  1373.         case FocusIn: ErrorF("FocusIn event\n"); break;
  1374.         case FocusOut: ErrorF("FocusOut event\n"); break;
  1375.         case KeymapNotify: ErrorF("KeymapNotify event\n"); break;
  1376.         case Expose: ErrorF("Expose event\n"); break;
  1377.         case GraphicsExpose: ErrorF("GraphicsExpose event\n"); break;
  1378.         case NoExpose: ErrorF("NoExpose event\n"); break;
  1379.         case VisibilityNotify: ErrorF("VisibilityNotify event\n"); break;
  1380.         case CreateNotify: ErrorF("CreateNotify event\n"); break;
  1381.         case DestroyNotify: ErrorF("DestroyNotify event\n"); break;
  1382.         case UnmapNotify: ErrorF("UnmapNotify event\n"); break;
  1383.         case MapNotify: ErrorF("MapNotify event\n"); break;
  1384.         case MapRequest: ErrorF("MapRequest event\n"); break;
  1385.         case ReparentNotify: ErrorF("ReparentNotify event\n"); break;
  1386.         case ConfigureNotify: ErrorF("ConfigureNotify event\n"); break;
  1387.         case ConfigureRequest: ErrorF("ConfigureRequest event\n"); break;
  1388.         case GravityNotify: ErrorF("GravityNotify event\n"); break;
  1389.         case ResizeRequest: ErrorF("ResizeRequest event\n"); break;
  1390.         case CirculateNotify: ErrorF("CirculateNotify event\n"); break;
  1391.         case CirculateRequest: ErrorF("CirculateRequest event\n"); break;
  1392.         case PropertyNotify: ErrorF("PropertyNotify event\n"); break;
  1393.         case SelectionClear: ErrorF("SelectionClear event\n"); break;
  1394.         case SelectionRequest: ErrorF("SelectionRequest event\n"); break;
  1395.         case SelectionNotify: ErrorF("SelectionNotify event\n"); break;
  1396.         case ColormapNotify: ErrorF("ColormapNotify event\n"); break;
  1397.         case ClientMessage: ErrorF("ClientMessage event\n"); break;
  1398.         case MappingNotify: ErrorF("MappingNotify event\n"); break;
  1399.         default:
  1400.             ErrorF("Data\n");
  1401.         }
  1402.     }
  1403.     }
  1404.     return (numBytes);
  1405. }
  1406. @
  1407.  
  1408.  
  1409. 1.11
  1410. log
  1411. @Added support for PDEV_WRITE_ASYNC
  1412. (whichis easy, because writes were already async)
  1413. @
  1414. text
  1415. @d2 2
  1416. a3 3
  1417.  * newpdev.c --
  1418.  *    Functions for handling a connection to a client over a new
  1419.  *    pseudo-device.
  1420. d6 1
  1421. a6 1
  1422.  *    which the client reads, and a 2K input buffer, to which it writes.
  1423. d40 1
  1424. a40 1
  1425. "$Header: /a/X/src/cmds/Xsprite/os/RCS/pdev.c,v 1.10 88/11/28 10:37:45 ouster Exp $ SPRITE (Berkeley)";
  1426. d489 2
  1427. d611 3
  1428. a613 1
  1429.     
  1430. d821 1
  1431. a821 1
  1432.     Pdev_Reply     reply;
  1433. d909 2
  1434. d925 2
  1435. a926 1
  1436.         int        replyBuf;
  1437. d953 1
  1438. a953 1
  1439.              * XXX: This should be handled by the
  1440. d977 8
  1441. d986 1
  1442. a986 1
  1443.                    IOC_PDEV_REPLY,
  1444. d1001 2
  1445. @
  1446.  
  1447.  
  1448. 1.10
  1449. log
  1450. @Changes for new pdev header format.
  1451. @
  1452. text
  1453. @d41 1
  1454. a41 1
  1455. "$Header: pdev.c,v 1.9 88/10/01 10:55:51 ouster Exp $ SPRITE (Berkeley)";
  1456. d647 3
  1457. d884 1
  1458. @
  1459.  
  1460.  
  1461. 1.9
  1462. log
  1463. @Change FS_NEW_MASTER => FS_PDEV_MASTER.
  1464. @
  1465. text
  1466. @d41 1
  1467. a41 1
  1468. "$Header: pdev.c,v 1.8 88/09/16 10:57:37 ouster Exp $ SPRITE (Berkeley)";
  1469. d291 1
  1470. a291 1
  1471.     pdevPriv->curPtrs.requestFirstByte += pdevPriv->reqPtr->messageSize;
  1472. d477 1
  1473. a477 1
  1474.         if (pdevPriv->reqPtr->operation == PDEV_CLOSE) {
  1475. d598 1
  1476. a598 1
  1477.         (pdevPriv->reqPtr->operation != PDEV_OPEN)) {
  1478. d647 3
  1479. a649 3
  1480.     if ((pdevReq->magic != PDEV_REQUEST_MAGIC) ||
  1481.         (pdevReq->operation != PDEV_WRITE) ||
  1482.         (pdevReq->requestSize < sizeof(xConnClientPrefix))) {
  1483. d880 1
  1484. a880 1
  1485.     switch (pdevPriv->reqPtr->operation) {
  1486. d885 1
  1487. a885 1
  1488.                pdevPriv->reqPtr->requestSize);
  1489. d926 1
  1490. a926 1
  1491.         if (pdevPriv->reqPtr->requestSize) {
  1492. d935 1
  1493. a935 1
  1494.                pdevPriv->reqPtr->requestSize,
  1495. d937 1
  1496. a937 1
  1497.                pdevPriv->reqPtr->replySize);
  1498. d985 1
  1499. a985 1
  1500.                pdevPriv->reqPtr->operation,
  1501. d1016 1
  1502. a1016 1
  1503.     need = min(pdevPriv->need, pdevPriv->reqPtr->requestSize);
  1504. d1026 1
  1505. a1026 1
  1506.         pdevPriv->reqPtr->requestSize -= need;
  1507. d1046 1
  1508. a1046 1
  1509.     need = min(pdevPriv->need, pdevPriv->reqPtr->requestSize);
  1510. d1089 2
  1511. a1090 2
  1512.     if (pdevPriv->reqPtr->requestSize < sizeof(xReq)) {
  1513.     if (pdevPriv->reqPtr->requestSize != 0) {
  1514. d1099 1
  1515. a1099 1
  1516.             pdevPriv->reqPtr->requestSize);
  1517. d1101 2
  1518. a1102 2
  1519.         pdevPriv->bigReq + pdevPriv->reqPtr->requestSize;
  1520.         pdevPriv->need = sizeof(xReq) - pdevPriv->reqPtr->requestSize;
  1521. d1114 1
  1522. a1114 1
  1523.     if (need > pdevPriv->reqPtr->requestSize) {
  1524. d1125 1
  1525. a1125 1
  1526.             pdevPriv->reqPtr->requestSize);
  1527. d1127 2
  1528. a1128 2
  1529.         pdevPriv->bigReq + pdevPriv->reqPtr->requestSize;
  1530.         pdevPriv->need = need - pdevPriv->reqPtr->requestSize;
  1531. d1135 1
  1532. a1135 1
  1533.         pdevPriv->reqPtr->requestSize -= need;
  1534. @
  1535.  
  1536.  
  1537. 1.8
  1538. log
  1539. @In changing to new C library goofed umask arguments.
  1540. @
  1541. text
  1542. @d41 1
  1543. a41 1
  1544. "$Header: pdev.c,v 1.7 88/09/11 13:09:20 ouster Exp $ SPRITE (Berkeley)";
  1545. d157 1
  1546. a157 1
  1547.         FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_NEW_MASTER,
  1548. @
  1549.  
  1550.  
  1551. 1.7
  1552. log
  1553. @Typo in last mod.
  1554. @
  1555. text
  1556. @d41 1
  1557. a41 1
  1558. "$Header: pdev.c,v 1.6 88/09/11 13:01:04 ouster Exp $ SPRITE (Berkeley)";
  1559. d155 1
  1560. a155 1
  1561.     oldPermMask = umask(0777);
  1562. @
  1563.  
  1564.  
  1565. 1.6
  1566. log
  1567. @Switch to use errno for errors.
  1568. @
  1569. text
  1570. @d41 1
  1571. a41 1
  1572. "$Header: pdev.c,v 1.5 88/09/09 18:00:25 ouster Exp $ SPRITE (Berkeley)";
  1573. d160 1
  1574. a160 1
  1575.     errno = CompatMapCode(status);
  1576. d313 1
  1577. a313 1
  1578.     errno = CompatMapCode(status);
  1579. d1245 1
  1580. a1245 1
  1581.         errno = CompatMapCode(status);
  1582. @
  1583.  
  1584.  
  1585. 1.5
  1586. log
  1587. @Include bit.h.
  1588. @
  1589. text
  1590. @d41 1
  1591. a41 1
  1592. "$Header: pdev.c,v 1.4 88/09/08 18:15:52 ouster Exp $ SPRITE (Berkeley)";
  1593. d147 1
  1594. d156 8
  1595. a163 7
  1596.     if (Fs_Open (deviceName,
  1597.           FS_NON_BLOCKING | FS_CREATE | FS_READ | FS_NEW_MASTER,
  1598.           0666,
  1599.           &Pdev_Conn) != 0) {
  1600.               Error (deviceName);
  1601.               FatalError ("Could not open pseudo-device %s",
  1602.                   deviceName);
  1603. d288 2
  1604. d309 8
  1605. a316 8
  1606.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1607.              sizeof(pdevPriv->curPtrs),
  1608.              (Address)&pdevPriv->curPtrs,
  1609.              0,
  1610.              (Address)NULL) != 0) {
  1611.              if (DBG(PDEV)) {
  1612.                  Error("RequestHandled: SET_PTRS");
  1613.              }
  1614. d1178 2
  1615. a1179 1
  1616.     register PdevPrivPtr pdevPriv;        /* Data private to client */
  1617. d1241 8
  1618. a1248 8
  1619.     if (Fs_IOControl(pdevPriv->streamID, IOC_PDEV_SET_PTRS,
  1620.              sizeof(pdevPriv->curPtrs),
  1621.              (Address)&pdevPriv->curPtrs,
  1622.              0,
  1623.              (Address)NULL) != 0) {
  1624.                  if (DBG(PDEV)) {
  1625.                  Error("WriteClient: SET_PTRS");
  1626.                  }
  1627. @
  1628.  
  1629.  
  1630. 1.4
  1631. log
  1632. @Intermediate check-in while converting to new C library.
  1633. @
  1634. text
  1635. @d41 1
  1636. a41 1
  1637. "$Header: pdev.c,v 1.3 88/08/26 16:13:09 brent Exp $ SPRITE (Berkeley)";
  1638. d61 1
  1639. @
  1640.  
  1641.  
  1642. 1.3
  1643. log
  1644. @Converted to new, standard, pseudo-device definitions
  1645. @
  1646. text
  1647. @d41 1
  1648. a41 1
  1649. "$Header: newpdev.c,v 1.1 87/11/29 19:51:59 deboor Exp $ SPRITE (Berkeley)";
  1650. d44 12
  1651. a57 2
  1652. #define NEED_REPLIES /* For Debugging Only */
  1653.  
  1654. d62 4
  1655. d69 1
  1656. a69 1
  1657.  * one of the Io_Print functions and expects two arguments: the name of the
  1658. d152 3
  1659. a154 3
  1660.     Io_PrintString (deviceName, DEVICE_TEMPLATE, hostname, display);
  1661.     if ((Fs_SetDefPerm (0777, &oldPermMask) != SUCCESS) ||
  1662.         (Fs_Open (deviceName,
  1663. d157 1
  1664. a157 1
  1665.           &Pdev_Conn) != SUCCESS)) {
  1666. d163 1
  1667. a163 1
  1668.     (void) Fs_SetDefPerm (oldPermMask, &oldPermMask);
  1669. d308 1
  1670. a308 1
  1671.              (Address)NULL) != SUCCESS) {
  1672. d326 2
  1673. a327 1
  1674.  *      SUCCESS or an error status.
  1675. d340 1
  1676. a340 1
  1677.     SpriteTime          timeout;    /* Timeout interval for select */
  1678. d345 2
  1679. a346 2
  1680.     timeout.seconds = REASONABLE_TIME;
  1681.     timeout.microseconds = 0;
  1682. d348 4
  1683. a351 8
  1684.     if ((Fs_Select (pdevPriv->streamID+1, &timeout, selMask, (int *)0, (int *)0,
  1685.            &numReady) != SUCCESS) ||
  1686.     (numReady != 1)) {
  1687.         if (numReady == 0) {
  1688.         return (FS_TIMEOUT);
  1689.         } else {
  1690.         return (stat_LastError);
  1691.         }
  1692. d353 7
  1693. a359 7
  1694.     
  1695.     if (Fs_Read(pdevPriv->streamID, sizeof(bufPtrs), &bufPtrs,
  1696.         &numBytes) != SUCCESS) {
  1697.             if (DBG(PDEV)) {
  1698.             Error ("PdevWaitForReadable");
  1699.             }
  1700.             return (FAILURE);
  1701. d365 1
  1702. a365 1
  1703.     return (FAILURE);
  1704. d368 1
  1705. a368 1
  1706.     return (SUCCESS);
  1707. d391 2
  1708. a392 2
  1709.     SpriteTime          timeout;        /* Timeout for select */
  1710.     SpriteTime          *pTimeOut;
  1711. d404 1
  1712. a404 1
  1713.     length = String_Length (reason);
  1714. d427 1
  1715. a427 1
  1716.     String_Copy(reason, (char *)&c[1]);
  1717. d432 1
  1718. a432 1
  1719.              0, (Address)NULL) != SUCCESS) {
  1720. d438 2
  1721. a439 2
  1722.     timeout.seconds = REASONABLE_TIME;
  1723.     timeout.microseconds = 0;
  1724. d441 1
  1725. a441 1
  1726.     pTimeOut = (SpriteTime *)0;
  1727. d453 7
  1728. a459 7
  1729.     if ((Fs_Select (pdevPriv->streamID+1, pTimeOut, selMask, (int *)0,
  1730.             (int *)0, &numReady) != SUCCESS) ||
  1731.         (numReady != 1)) {
  1732.         if (DBG(PDEV)) {
  1733.             ErrorF("PdevConnFail: didn't read in reasonable time\n");
  1734.         }
  1735.         break;
  1736. d461 5
  1737. a465 5
  1738.     if ((Fs_Read(pdevPriv->streamID, sizeof(bufPtrs),
  1739.              &bufPtrs, &numBytes) != SUCCESS) ||
  1740.         (numBytes != sizeof(bufPtrs)) ||
  1741.         (bufPtrs.magic != PDEV_BUF_PTR_MAGIC)) {
  1742.         break;
  1743. d498 1
  1744. a498 1
  1745.     } while (!pTimeOut || (pTimeOut->seconds || pTimeOut->microseconds));
  1746. d526 1
  1747. a526 1
  1748.     PdevPrivPtr    pdevPriv;       /* New private information for us */
  1749. d530 1
  1750. a530 1
  1751.     Pdev_Reply     openReply;      /* Reply to open request */
  1752. d542 3
  1753. a544 5
  1754.     if ((Fs_Read(Pdev_Conn, sizeof(note),
  1755.              (Address)¬e, &numBytes) != SUCCESS) ||
  1756.         (numBytes != sizeof(note)) ||
  1757.         (note.magic != PDEV_NOTIFY_MAGIC)) {
  1758.         return;
  1759. d546 1
  1760. a546 1
  1761.     
  1762. d549 1
  1763. a549 1
  1764.     pdevPriv = (PdevPrivPtr)Mem_Alloc(sizeof(PdevPrivRec));
  1765. d564 1
  1766. a564 1
  1767.     pPriv = (ClntPrivPtr)Mem_Alloc(sizeof(ClntPrivRec));
  1768. d592 1
  1769. a592 1
  1770.     if ((PdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) ||
  1771. d594 3
  1772. a596 3
  1773.         (void)Fs_Close(pdevPriv->streamID);
  1774.         Mem_Free((Address)pdevPriv);
  1775.         Mem_Free((Address)pPriv);
  1776. d613 3
  1777. a615 3
  1778.         (void)Fs_Close(pdevPriv->streamID);
  1779.         Mem_Free((Address)pdevPriv);
  1780.         Mem_Free((Address)pPriv);
  1781. d634 4
  1782. a637 4
  1783.     if (PdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) {
  1784.         (void)Fs_Close(pdevPriv->streamID);
  1785.         Mem_Free((Address)pdevPriv);
  1786.         Mem_Free((Address)pPriv);
  1787. d645 3
  1788. a647 3
  1789.         (void)Fs_Close(pdevPriv->streamID);
  1790.         Mem_Free((Address)pdevPriv);
  1791.         Mem_Free((Address)pPriv);
  1792. d663 3
  1793. a665 3
  1794.         (void)Fs_Close(pdevPriv->streamID);
  1795.         Mem_Free((Address)pdevPriv);
  1796.         Mem_Free((Address)pPriv);
  1797. d672 3
  1798. a674 3
  1799.         (void)Fs_Close(pdevPriv->streamID);
  1800.         Mem_Free((Address)pdevPriv);
  1801.         Mem_Free((Address)pPriv);
  1802. d682 3
  1803. a684 3
  1804.         (void)Fs_Close(pdevPriv->streamID);
  1805.         Mem_Free((Address)pdevPriv);
  1806.         Mem_Free((Address)pPriv);
  1807. d757 1
  1808. a757 1
  1809.     Fs_Close(streamID);
  1810. d766 1
  1811. a766 1
  1812.     Mem_Free(pdevPriv->bigReq);
  1813. d769 1
  1814. a769 1
  1815.     Mem_Free ((Address)pdevPriv);
  1816. d821 1
  1817. a821 1
  1818.          * the device if we actually got here because Fs_Select says the
  1819. d825 17
  1820. a841 17
  1821.         if (Fs_Read(pdevPriv->streamID, sizeof(bufPtrs),
  1822.             &bufPtrs, &numBytes) != SUCCESS) {
  1823.                 if (stat_LastError != FS_WOULD_BLOCK) {
  1824.                 if (DBG(PDEV)) {
  1825.                     Error("Reading buffer pointers");
  1826.                 }
  1827.                 *pStatus = -1;
  1828.                 return((char *)NULL);
  1829.                 } else {
  1830.                 /*
  1831.                  * Wasn't actually anything to read. Go on to
  1832.                  * the next client...
  1833.                  */
  1834.                 *pStatus = 0;
  1835.                 SchedYield();
  1836.                 return ((char *)NULL);
  1837.                 }
  1838. d1012 1
  1839. a1012 3
  1840.     Byte_Copy(need,
  1841.           pdevPriv->inPtr,
  1842.           pdevPriv->bigReqPtr);
  1843. d1042 1
  1844. a1042 3
  1845.     Byte_Copy(need,
  1846.           pdevPriv->inPtr,
  1847.           pdevPriv->bigReqPtr);
  1848. d1062 1
  1849. a1062 1
  1850.         
  1851. d1065 2
  1852. a1066 4
  1853.         pdevPriv->bigReq = Mem_Alloc(need);
  1854.         Byte_Copy(sizeof(xReq),
  1855.               xreq,
  1856.               pdevPriv->bigReq);
  1857. d1070 1
  1858. a1070 1
  1859.         Mem_Free((char *)xreq);
  1860. d1081 1
  1861. a1081 1
  1862.     Mem_Free(pdevPriv->bigReq);
  1863. d1092 3
  1864. a1094 4
  1865.         pdevPriv->bigReq = (char *)Mem_Alloc(sizeof(xReq));
  1866.         Byte_Copy(pdevPriv->reqPtr->requestSize,
  1867.               pdevPriv->inPtr,
  1868.               pdevPriv->bigReq);
  1869. d1118 3
  1870. a1120 4
  1871.         pdevPriv->bigReq = (char *)Mem_Alloc(need);
  1872.         Byte_Copy(pdevPriv->reqPtr->requestSize,
  1873.               pdevPriv->inPtr,
  1874.               pdevPriv->bigReq);
  1875. d1197 1
  1876. a1197 3
  1877.     Byte_Copy(numWrite,
  1878.           (Address)xRepPtr,
  1879.           pdevPriv->outPtr);
  1880. d1227 1
  1881. a1227 1
  1882.         Byte_Copy(padding, (char *) &pad, pdevPriv->outPtr);
  1883. d1239 1
  1884. a1239 1
  1885.              (Address)NULL) != SUCCESS) {
  1886. @
  1887.  
  1888.  
  1889. 1.2
  1890. log
  1891. @Fixes to go with the latest implementation of  pseudo-devices
  1892. @
  1893. text
  1894. @a38 2
  1895. #ifdef NEWPDEV
  1896.  
  1897. d84 1
  1898. a84 1
  1899.     Pdev_NewRequest    *reqPtr;    /* Address of next request to process */
  1900. d104 1
  1901. a104 1
  1902. } NewPdevPrivRec, *NewPdevPrivPtr;
  1903. d106 3
  1904. a108 3
  1905. static void       NewPdevCloseClient();
  1906. static char       *NewPdevReadClient();
  1907. static int        NewPdevWriteClient();
  1908. d110 1
  1909. a110 1
  1910. int              NewPdev_Conn;
  1911. d114 1
  1912. a114 1
  1913.  * NewPdev_Init --
  1914. d127 1
  1915. a127 1
  1916. NewPdev_Init(hostname)
  1917. d143 1
  1918. a143 1
  1919.           &NewPdev_Conn) != SUCCESS)) {
  1920. d154 1
  1921. a154 1
  1922.  * NewPdevSetPtrs --
  1923. d169 2
  1924. a170 2
  1925. NewPdevSetPtrs(pdevPriv, bufPtrs)
  1926.     NewPdevPrivPtr    pdevPriv;
  1927. d173 1
  1928. a173 1
  1929.     if (DBG(NEWPDEV)) {
  1930. d195 1
  1931. a195 1
  1932.         (Pdev_NewRequest *)&pdevPriv->inBuf[bufPtrs->requestFirstByte];
  1933. d243 1
  1934. a243 1
  1935.          * Need to make this -1 so NewPdevWriteClient works correctly
  1936. d254 1
  1937. a254 1
  1938.  * NewPdevRequestHandled --
  1939. d268 2
  1940. a269 2
  1941. NewPdevRequestHandled(pdevPriv)
  1942.     NewPdevPrivPtr    pdevPriv;
  1943. d274 1
  1944. a274 1
  1945.     (Pdev_NewRequest *)&pdevPriv->inBuf[pdevPriv->curPtrs.requestFirstByte];
  1946. d281 1
  1947. a281 1
  1948.     if (DBG(NEWPDEV)) {
  1949. d295 1
  1950. a295 1
  1951.              if (DBG(NEWPDEV)) {
  1952. d307 1
  1953. a307 1
  1954.  * NewPdevWaitForReadable --
  1955. d320 2
  1956. a321 2
  1957. NewPdevWaitForReadable (pdevPriv, selMask)
  1958.     NewPdevPrivPtr    pdevPriv;   /* Connection to read */
  1959. d345 2
  1960. a346 2
  1961.             if (DBG(NEWPDEV)) {
  1962.             Error ("NewPdevWaitForReadable");
  1963. d351 1
  1964. a351 1
  1965.     if (DBG(NEWPDEV)) {
  1966. d356 1
  1967. a356 1
  1968.     NewPdevSetPtrs(pdevPriv, &bufPtrs);
  1969. d362 1
  1970. a362 1
  1971.  * NewPdevConnFail --
  1972. d374 2
  1973. a375 2
  1974. NewPdevConnFail (pdevPriv, swapped, reason)
  1975.     NewPdevPrivPtr    pdevPriv;       /* Failed connection */
  1976. d429 1
  1977. a429 1
  1978.     if (DBG(NEWPDEV)) {
  1979. d445 2
  1980. a446 2
  1981.         if (DBG(NEWPDEV)) {
  1982.             ErrorF("NewPdevConnFail: didn't read in reasonable time\n");
  1983. d459 1
  1984. a459 1
  1985.         NewPdevSetPtrs(pdevPriv, &bufPtrs);
  1986. d467 1
  1987. a467 1
  1988.             Pdev_NewReply    reply;
  1989. d478 1
  1990. a478 1
  1991.             NewPdevRequestHandled(pdevPriv);
  1992. d484 1
  1993. a484 1
  1994.         NewPdevRequestHandled(pdevPriv);
  1995. d495 1
  1996. a495 1
  1997.  * NewPdev_EstablishNewConnections --
  1998. d509 1
  1999. a509 1
  2000. NewPdev_EstablishNewConnections (pNewClients, pNumNew)
  2001. d515 1
  2002. a515 1
  2003.     NewPdevPrivPtr    pdevPriv;       /* New private information for us */
  2004. d518 2
  2005. a519 2
  2006.     Pdev_NewRequest    *pdevReq;       /* Pointer to current request */
  2007.     Pdev_NewReply     openReply;      /* Reply to open request */
  2008. d531 1
  2009. a531 1
  2010.     if ((Fs_Read(NewPdev_Conn, sizeof(note),
  2011. d540 1
  2012. a540 1
  2013.     pdevPriv = (NewPdevPrivPtr)Mem_Alloc(sizeof(NewPdevPrivRec));
  2014. d556 3
  2015. a558 3
  2016.     pPriv->readProc =                       NewPdevReadClient;
  2017.     pPriv->writeProc =                      NewPdevWriteClient;
  2018.     pPriv->closeProc =                      NewPdevCloseClient;
  2019. d583 1
  2020. a583 1
  2021.     if ((NewPdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) ||
  2022. d616 1
  2023. a616 1
  2024.     NewPdevRequestHandled(pdevPriv);
  2025. d625 1
  2026. a625 1
  2027.     if (NewPdevWaitForReadable(pdevPriv, pPriv->ready) != SUCCESS) {
  2028. d652 2
  2029. a653 2
  2030.         NewPdevRequestHandled(pdevPriv);
  2031.         NewPdevConnFail(pdevPriv, swapped, "Protocol version mismatch");
  2032. d660 2
  2033. a661 2
  2034.         NewPdevRequestHandled(pdevPriv);
  2035.         NewPdevConnFail(pdevPriv, swapped,
  2036. d669 1
  2037. a669 1
  2038.     client = NextAvailableClient();
  2039. d671 2
  2040. a672 2
  2041.         NewPdevRequestHandled(pdevPriv);
  2042.         NewPdevConnFail(pdevPriv, swapped, "Too many clients");
  2043. d683 1
  2044. a683 1
  2045.     NewPdevRequestHandled(pdevPriv);
  2046. d685 2
  2047. a686 2
  2048.     if (DBG(NEWPDEV) || DBG(CONN)) {
  2049.         ErrorF ("New NewPdev connection: client %d (newID = %d)\n",
  2050. d721 1
  2051. a721 1
  2052.  * NewPdevCloseClient --
  2053. d738 1
  2054. a738 1
  2055. NewPdevCloseClient (pPriv)
  2056. d742 1
  2057. a742 1
  2058.     register NewPdevPrivPtr pdevPriv;
  2059. d745 1
  2060. a745 1
  2061.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2062. d770 1
  2063. a770 1
  2064.  * NewPdevReadClient --
  2065. d787 1
  2066. a787 1
  2067. NewPdevReadClient (pPriv, pStatus, oldbuf)
  2068. d795 1
  2069. a795 1
  2070.     NewPdevPrivPtr      pdevPriv;   /* Private data for the client */
  2071. d801 1
  2072. a801 1
  2073.     Pdev_NewReply     reply;
  2074. d803 1
  2075. a803 1
  2076.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2077. d819 1
  2078. a819 1
  2079.                 if (DBG(NEWPDEV)) {
  2080. d836 1
  2081. a836 1
  2082.             if (DBG(NEWPDEV)) {
  2083. d842 1
  2084. a842 1
  2085.         NewPdevSetPtrs(pdevPriv, &bufPtrs);
  2086. d847 1
  2087. a847 1
  2088.          * be done. NewPdevSetPtrs will have copied any overflow
  2089. d868 1
  2090. a868 1
  2091.         if (DBG(NEWPDEV)) {
  2092. d880 1
  2093. a880 1
  2094.         if (DBG(NEWPDEV) || DBG(CONN)) {
  2095. d892 1
  2096. a892 1
  2097.         NewPdevRequestHandled(pdevPriv);
  2098. d917 1
  2099. a917 1
  2100.         if (DBG(NEWPDEV)) {
  2101. d946 1
  2102. a946 1
  2103.             if (DBG(NEWPDEV)) {
  2104. d957 1
  2105. a957 1
  2106.         NewPdevRequestHandled(pdevPriv);
  2107. d969 1
  2108. a969 1
  2109.         if (DBG(NEWPDEV)) {
  2110. d978 1
  2111. a978 1
  2112.         NewPdevRequestHandled(pdevPriv);
  2113. d1010 1
  2114. a1010 1
  2115.         NewPdevRequestHandled(pdevPriv);
  2116. d1019 1
  2117. a1019 1
  2118.         if (DBG(NEWPDEV)) {
  2119. d1045 1
  2120. a1045 1
  2121.         NewPdevRequestHandled(pdevPriv);
  2122. d1097 1
  2123. a1097 1
  2124.     NewPdevRequestHandled(pdevPriv);
  2125. d1123 1
  2126. a1123 1
  2127.         NewPdevRequestHandled(pdevPriv);
  2128. d1132 1
  2129. a1132 1
  2130.         if (DBG(NEWPDEV)) {
  2131. d1143 1
  2132. a1143 1
  2133.  * NewPdevWriteClient --
  2134. d1163 1
  2135. a1163 1
  2136. NewPdevWriteClient (pPriv, numBytes, xRepPtr)
  2137. d1172 1
  2138. a1172 1
  2139.     register NewPdevPrivPtr pdevPriv;        /* Data private to client */
  2140. d1176 1
  2141. a1176 1
  2142.     pdevPriv = (NewPdevPrivPtr) pPriv->devicePrivate;
  2143. d1185 1
  2144. a1185 1
  2145.     if (DBG(NEWPDEV)) {
  2146. d1241 1
  2147. a1241 1
  2148.                  if (DBG(NEWPDEV)) {
  2149. d1245 1
  2150. a1245 1
  2151.     if (DBG(NEWPDEV)) {
  2152. a1301 2
  2153.  
  2154. #endif NEWPDEV
  2155. @
  2156.  
  2157.  
  2158. 1.1
  2159. log
  2160. @Initial revision
  2161. @
  2162. text
  2163. @d39 2
  2164. d43 1
  2165. a43 1
  2166. "$Header: pdev.c,v 1.1 87/11/01 20:17:30 deboor Exp $ SPRITE (Berkeley)";
  2167. d60 1
  2168. a60 1
  2169. #define    DEVICE_TEMPLATE    "/hosts/%s/X1%s"
  2170. d335 1
  2171. a335 1
  2172.     if ((Fs_Select (pdevPriv->streamID+1, /*&timeout*/ (SpriteTime *)0, selMask, (int *)0, (int *)0,
  2173. d462 26
  2174. d489 1
  2175. a489 1
  2176.     } while (1);
  2177. d491 1
  2178. d527 1
  2179. d530 1
  2180. d574 3
  2181. d654 1
  2182. d662 1
  2183. d673 1
  2184. d1304 2
  2185. @
  2186.